/*****************************************************************************
#
#
******************************************************************************/
#include "EPD_2in9b_Z94_Grey.h"
#include "DEBUG.h"
// #include "EPD_SDCard.h"

#define DEBUG Debug

static uint8_t iLut = 0;

/******************************************************************************
function :	Software reset
parameter:
******************************************************************************/
static void EPD_2IN9B_Z94_Grey_Reset(void)
{
    // DEV_Digital_Write(EPD_RST_PIN, 1);
    // DEV_Delay_ms(10);
    DEV_Digital_Write(EPD_RST_PIN, 0);
    DEV_Delay_ms(10);
    DEV_Digital_Write(EPD_RST_PIN, 1);
    DEV_Delay_ms(10);
}

/******************************************************************************
function :	send command
parameter:
     Reg : Command register
******************************************************************************/
static void EPD_2IN9B_Z94_Grey_SendCommand(UBYTE Reg)
{
    DEV_Digital_Write(EPD_DC_PIN, 0);
    // DEV_Digital_Write(EPD_CS_PIN, 0);
    DEV_SPI_WriteByte(Reg);
    // DEV_Digital_Write(EPD_CS_PIN, 1);
}

/******************************************************************************
function :	send data
parameter:
    Data : Write data
******************************************************************************/

static void EPD_2IN9B_Z94_Grey_SendData(UBYTE Data)
{
    DEV_Digital_Write(EPD_DC_PIN, 1);
    // DEV_Digital_Write(EPD_CS_PIN, 0);
    DEV_SPI_WriteByte(Data);
    // DEV_Digital_Write(EPD_CS_PIN, 1);
}

static void EPD_2IN9B_Z94_Grey_SendData2(UBYTE *Data, UDOUBLE length)
{
    DEV_SPI_WriteByte(Data, length);
}

static void EPD_2IN9B_Z94_Grey_SendData2(UBYTE Data)
{
    // DEV_Digital_Write(EPD_DC_PIN, 1);
    // DEV_Digital_Write(EPD_CS_PIN, 0);
    DEV_SPI_WriteByte(Data);
    // DEV_Digital_Write(EPD_CS_PIN, 1);
}

#define _VS(x) x << 6
#define VSS _VS(0b00)
#define VSH1 _VS(0b01)
#define VSL _VS(0b10)
#define VSH2 _VS(0b11)

/* LUT lite is small than LUT used in SSD1680A, only 35 bytes.
 * lut_lite_fast_bw is default lut for clock display,
 * lut_lite_gray8_bwr is default lut for BLE display.
 */
#define LUT_LITE_LEN 35

// LUT for clock fast display. (only black/white)
static const uint8_t lut_lite_fast_bw[LUT_LITE_LEN] = {
    //  RP      A           B           C           D           SRAB    SRCD
    0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,                // LUTC
    0x1, VSL | 0x2f, 0x0, VSH2 | 0x3f, 0x0, 0x1, 0x0, // LUTR
    0x1, VSL | 0x3f, 0x0, 0x0, 0x0, 0x1, 0x0,         // LUTW
    0x1, VSH1 | 0x2f, 0x0, 0x0, 0x0, 0x1, 0x0,        // LUTB

    //  FR
    0x04, // 2: 50hz, 3: 75Hz, 4: 100Hz, 5: 125Hz

    //  EOPT    VGH     VSH1    VSH2    VSL     VCOM
    //  3F      03      04                      2C
    //  22      -20v    15v     3v      -15v
    0x22, 0x17, 0x41, 0x94, 0x32, 0x36};

// // LUT for BLE Gray display (8 steps)
// static const uint8_t lut_lite_gray8_bwr[LUT_LITE_LEN] = {
// //  RP      A           B           C           D           SRAB    SRCD
//     0x0,    0x0,        0x0,        0x0,        0x0,        0x0,    0x0,            // LUTC
//     0x1,    VSH2|0x3f,  0x0,        0x0,        0x0,        0x1,    0x0,            // LUTR
//     0x0,    0x0,        0x0,        0x0,        0x0,        0x0,    0x0,            // LUTW
//     0x1,    VSH1|0x03,  0x0,        0x0,        0x0,        0x1,    0x0,            // LUTB

// //  FR
//     0x04, // 2: 50hz, 3: 75Hz, 4: 100Hz, 5: 125Hz

// //  EOPT    VGH     VSH1    VSH2    VSL     VCOM
// //  3F      03      04                      2C
// //  22      -20v    15v     3.0v      -15v
//     0x22,   0x17,   0x41,   0x94,   0x32,   0x36
// };

// // LUT for BLE Gray display (8 steps)//xz useful
// static const uint8_t lut_lite_gray8_bwr[LUT_LITE_LEN] = {
// //  RP      A           B           C           D           SRAB    SRCD
//     0x0,    0x0,        0x0,        0x0,        0x0,        0x0,    0x0,            // LUTC
//     0x1,    VSH2|0x3f,  0x0,        0x0,        0x0,        0x3,    0x0,            // LUTR
//     0x0,    0x0,        0x0,        0x0,        0x0,        0x0,    0x0,            // LUTW
//     0x1,    VSH1|0x03,  0x0,        0x0,        0x0,        0x2,    0x0,            // LUTB

// //  FR
//     0x04, // 2: 50hz, 3: 75Hz, 4: 100Hz, 5: 125Hz

// //  EOPT    VGH     VSH1    VSH2    VSL     VCOM
// //  3F      03      04                      2C
// //  22      -20v    15v     3.0v      -15v
//     0x22,   0x17,   0x41,   0x94,   0x32,   0x36
// };

// // LUT for BLE Gray display (8 steps)//useful
// static const uint8_t lut_lite_gray8_bwr[LUT_LITE_LEN] = {
// //  RP      A           B           C           D           SRAB    SRCD
//     0x0,    0x0,        0x0,        0x0,        0x0,        0x0,    0x0,            // LUTC
//     0x1,    VSH2|0x10,  0x0,        0x0,        0x0,        0x2,    0x0,            // LUTR
//     0x0,    0x0,        0x0,        0x0,        0x0,        0x0,    0x0,            // LUTW
//     0x1,    VSH1|0x03,  0x0,        0x0,        0x0,        0x2,    0x0,            // LUTB

// //  FR
//     0x04, // 2: 50hz, 3: 75Hz, 4: 100Hz, 5: 125Hz

// //  EOPT    VGH     VSH1    VSH2    VSL     VCOM
// //  3F      03      04                      2C
// //  22      -20v    15v     5v      -15v
//     0x22,   0x17,   0x41,   0xA8,   0x32,   0x36
// };

// LUT for BLE Gray display (4 steps)//4grey
static const uint8_t lut_lite_grey4_bwr[LUT_LITE_LEN] = {
    //  RP      A           B           C           D           SRAB    SRCD
    0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,          // LUTC
    0x1, VSH2 | 0x13, 0x0, 0x0, 0x0, 0x05, 0x0, // LUTR
    0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,          // LUTW
    0x1, VSH1 | 0x0C, 0x0, 0x0, 0x0, 0x01, 0x0, // LUTB

    //  FR
    0x04, // 2: 50hz, 3: 75Hz, 4: 100Hz, 5: 125Hz

    //  EOPT    VGH     VSH1    VSH2    VSL     VCOM
    //  3F      03      04                      2C
    //  22      -20v    15v     5v      -15v
    0x22, 0x17, 0x41, 0xA8, 0x32, 0x36};

// LUT for BLE Gray display (8 steps)//8grey
static const uint8_t lut_lite_grey8_bwr[LUT_LITE_LEN] = {
    //  RP      A           B           C           D           SRAB    SRCD
    0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,         // LUTC
    0x1, VSH2 | 0x3F, 0x0, 0x0, 0x0, 0x1, 0x0, // LUTR
    0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,         // LUTW
    0x1, VSH1 | 0x06, 0x0, 0x0, 0x0, 0x1, 0x0, // LUTB

    //  FR
    0x04, // 2: 50hz, 3: 75Hz, 4: 100Hz, 5: 125Hz

    //  EOPT    VGH     VSH1    VSH2    VSL     VCOM
    //  3F      03      04                      2C
    //  22      -20v    15v     5v      -15v
    0x22, 0x0, 0x41, 0xA8, 0x32, 0x0};

// // LUT for BLE Gray display (8 steps)//8grey_back
// static const uint8_t lut_lite_grey8_bwr[LUT_LITE_LEN] = {
//     //  RP      A           B           C           D           SRAB    SRCD
//     0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,         // LUTC
//     0x1, VSH2 | 0x05, 0x0, 0x0, 0x0, 0x6, 0x0, // LUTR
//     0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,         // LUTW
//     0x1, VSH1 | 0x05, 0x0, 0x0, 0x0, 0x1, 0x0, // LUTB

//     //  FR
//     0x04, // 2: 50hz, 3: 75Hz, 4: 100Hz, 5: 125Hz

//     //  EOPT    VGH     VSH1    VSH2    VSL     VCOM
//     //  3F      03      04                      2C
//     //  22      -20v    15v     5v      -15v
//     0x22, 0x17, 0x41, 0xA8, 0x32, 0x36};

// LUT for BLE Gray display (16 steps)//16grey
static const uint8_t lut_lite_grey16_bwr[LUT_LITE_LEN] = {
    //  RP      A           B           C           D           SRAB    SRCD
    0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,         // LUTC
    0x1, VSH2 | 0x05, 0x0, 0x0, 0x0, 0x3, 0x0, // LUTR
    0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,         // LUTW
    0x1, VSH1 | 0x03, 0x0, 0x0, 0x0, 0x1, 0x0, // LUTB

    //  FR
    0x04, // 2: 50hz, 3: 75Hz, 4: 100Hz, 5: 125Hz

    //  EOPT    VGH     VSH1    VSH2    VSL     VCOM
    //  3F      03      04                      2C
    //  22      -20v    15v     5v      -15v
    0x22, 0x17, 0x41, 0xA8, 0x32, 0x36};

static const uint8_t lut_lite_grey4_bwr_array[3][4] = {
    {VSH2 | 0x13, 0x07, VSH1 | 0x0F, 0x01}, // ilut1
    {VSH2 | 0x13, 0x02, VSH1 | 0x09, 0x01}, // ilut2
    {VSH2 | 0x13, 0x06, VSH1 | 0x0C, 0x01}, // ilut3
};

static const uint8_t lut_lite_grey8_bwr_array[7][4] = {
    {VSH2 | 0x05, 0x0F, VSH1 | 0x06, 0x01}, // ilut1
    {VSH2 | 0x05, 0x0F, VSH1 | 0x06, 0x01}, // ilut2
    {VSH2 | 0x05, 0x0E, VSH1 | 0x06, 0x01}, // ilut3
    {VSH2 | 0x05, 0x0B, VSH1 | 0x06, 0x01}, // ilut4
    {VSH2 | 0x05, 0x0C, VSH1 | 0x06, 0x01}, // ilut5
    {VSH2 | 0x05, 0x0A, VSH1 | 0x06, 0x01}, // ilut6
    {VSH2 | 0x05, 0x0D, VSH1 | 0x06, 0x01}, // ilut7
};

static void EPD_2IN9B_Z94_Grey_Lut(const unsigned char *lut)
{
    // SSD1680A uses 233 LUT.

    // 0, wareform setting
    EPD_2IN9B_Z94_Grey_SendCommand(0x32);
    for (int j = 0; j < 4; j++)
    { // LUT0-3
        // wave setting
        for (int i = 0; i < 7; i++)
        {
            EPD_2IN9B_Z94_Grey_SendData(lut[j * 7 + i]);
        }
        // no config
        for (int i = 0; i < 7 * 7; i++)
        {
            EPD_2IN9B_Z94_Grey_SendData(0x00);
        }
    }
    // 4 * (7+49) = 224

    // 224, FR
    // 2: 50hz, 3: 75Hz, 4: 100Hz, 5: 125Hz
    EPD_2IN9B_Z94_Grey_SendData(lut[28]);

    // 225, XON
    EPD_2IN9B_Z94_Grey_SendData(0x00);
    EPD_2IN9B_Z94_Grey_SendData(0x00);

    //  EOPT    VGH     VSH1    VSH2    VSL     VCOM
    //  3F      03      04                      2C
    //  22      -20v    15v     3v      -15v
    //  0x22,   0x17,   0x41,   0x94,   0x32,   0x36

    // 227, gate voltage
    EPD_2IN9B_Z94_Grey_SendCommand(0x3F);
    EPD_2IN9B_Z94_Grey_SendData(lut[29]);

    EPD_2IN9B_Z94_Grey_SendCommand(0x03);
    EPD_2IN9B_Z94_Grey_SendData(lut[30]);

    // 229, source voltage
    EPD_2IN9B_Z94_Grey_SendCommand(0x04);
    EPD_2IN9B_Z94_Grey_SendData(lut[31]); // VSH
    EPD_2IN9B_Z94_Grey_SendData(lut[32]); // VSH2
    EPD_2IN9B_Z94_Grey_SendData(lut[33]); // VSL

    // 232, VCOM
    EPD_2IN9B_Z94_Grey_SendCommand(0x2C);
    EPD_2IN9B_Z94_Grey_SendData(lut[34]);
}

/******************************************************************************
function :	Wait until the busy_pin goes LOW
parameter:
******************************************************************************/
static void EPD_2IN9B_Z94_Grey_ReadBusy(void)
{
    DEBUG("e-Paper busy\r\n");
    while (1)
    {
        if (DEV_Digital_Read(EPD_BUSY_PIN) == 0)
            break;
        DEV_Delay_ms(10);
    }

    DEBUG("e-Paper busy release\r\n");
}



void EPD_2IN9B_Z94_Grey_ReadBusy(uint32_t ms)
{
    Debug("e-Paper busy:%d\r\n", millis());
    for (uint32_t i = 0; i < ms; i += 10)
   {
        if (!DEV_Digital_Read(EPD_BUSY_PIN))
        {
            Debug("e-Paper busy release:%d\r\n", millis());
            return;
        }
        if (ms > 200)
        {
#ifndef  TEST             
            EPD_BUSY_attachInterrupt(LOW);
#else
            DEV_Delay_ms(10);       
#endif
        }
        else
            DEV_Delay_ms(10);
    }
    Debug("e-Paper busy timeout:%d\r\n", millis());
}

/******************************************************************************
function :	Initialize the e-Paper register
parameter:
******************************************************************************/
void EPD_2IN9B_Z94_Grey_Init(uint8_t lut_type)
{

    EPD_2IN9B_Z94_Grey_Reset();

    EPD_2IN9B_Z94_Grey_ReadBusy(100);
    EPD_2IN9B_Z94_Grey_SendCommand(0x12); // SWRESET
    EPD_2IN9B_Z94_Grey_ReadBusy(100);

    EPD_2IN9B_Z94_Grey_SendCommand(0x01); // Driver output control
    EPD_2IN9B_Z94_Grey_SendData((EPD_2IN9B_Z94_Grey_HEIGHT - 1) % 256);
    EPD_2IN9B_Z94_Grey_SendData((EPD_2IN9B_Z94_Grey_HEIGHT - 1) / 256);
    EPD_2IN9B_Z94_Grey_SendData(0x00);

    EPD_2IN9B_Z94_Grey_SendCommand(0x11); // data entry mode
    EPD_2IN9B_Z94_Grey_SendData(0x03);

    EPD_2IN9B_Z94_Grey_SendCommand(0x44); // set Ram-X address start/end position
    EPD_2IN9B_Z94_Grey_SendData(0x00);
    EPD_2IN9B_Z94_Grey_SendData(EPD_2IN9B_Z94_Grey_WIDTH / 8 - 1);

    EPD_2IN9B_Z94_Grey_SendCommand(0x45); // set Ram-Y address start/end position
    EPD_2IN9B_Z94_Grey_SendData(0x00);
    EPD_2IN9B_Z94_Grey_SendData(0x00);
    EPD_2IN9B_Z94_Grey_SendData((EPD_2IN9B_Z94_Grey_HEIGHT - 1) % 256);
    EPD_2IN9B_Z94_Grey_SendData((EPD_2IN9B_Z94_Grey_HEIGHT - 1) / 256);

    EPD_2IN9B_Z94_Grey_SendCommand(0x3C); // BorderWavefrom
    EPD_2IN9B_Z94_Grey_SendData(0x05);

    EPD_2IN9B_Z94_Grey_SendCommand(0x21); //  Display update control
    EPD_2IN9B_Z94_Grey_SendData(0x00);
    EPD_2IN9B_Z94_Grey_SendData(0x80);

    EPD_2IN9B_Z94_Grey_SendCommand(0x18); // Read built-in temperature sensor
    EPD_2IN9B_Z94_Grey_SendData(0x80);

    EPD_2IN9B_Z94_Grey_SendCommand(0x4E); // set RAM x address count to 0;
    EPD_2IN9B_Z94_Grey_SendData(0x00);
    EPD_2IN9B_Z94_Grey_SendCommand(0x4F); // set RAM y address count to 0X199;
    EPD_2IN9B_Z94_Grey_SendData(0x00);
    EPD_2IN9B_Z94_Grey_SendData(0x00);
    // EPD_2IN9B_Z94_Grey_SendData((EPD_2IN9B_Z94_Grey_HEIGHT - 1) % 256);
    // EPD_2IN9B_Z94_Grey_SendData((EPD_2IN9B_Z94_Grey_HEIGHT - 1) / 256);

    if (lut_type)
    {
        if (lut_type == EPD_2IN9B_Grey_Bwr8)
        {
            uint8_t lut_temp[LUT_LITE_LEN];
            memcpy(lut_temp, lut_lite_grey8_bwr, LUT_LITE_LEN);
            if (iLut > 0 && iLut < 8)
            {
                lut_temp[8] = lut_lite_grey8_bwr_array[iLut - 1][0];
                lut_temp[12] = lut_lite_grey8_bwr_array[iLut - 1][1];
                lut_temp[22] = lut_lite_grey8_bwr_array[iLut - 1][2];
                lut_temp[26] = lut_lite_grey8_bwr_array[iLut - 1][3];
            }
            EPD_2IN9B_Z94_Grey_Lut(lut_temp);
        }
        else if (lut_type == EPD_2IN9B_Grey_Bwr8)
            EPD_2IN9B_Z94_Grey_Lut(lut_lite_grey8_bwr);
        else if (lut_type == EPD_2IN9B_Grey_Bwr16)
            EPD_2IN9B_Z94_Grey_Lut(lut_lite_grey16_bwr);
    }
    EPD_2IN9B_Z94_Grey_ReadBusy(100);
}

/******************************************************************************
function :	Clear screen
parameter:
******************************************************************************/
void EPD_2IN9B_Z94_Grey_Clear(void)
{
    UDOUBLE Width, Height;
    Width = (EPD_2IN9B_Z94_Grey_WIDTH % 8 == 0) ? (EPD_2IN9B_Z94_Grey_WIDTH / 8) : (EPD_2IN9B_Z94_Grey_WIDTH / 8 + 1);
    Height = EPD_2IN9B_Z94_Grey_HEIGHT;

    unsigned int i;
    EPD_2IN9B_Z94_Grey_SendCommand(0x24); // write RAM for black(0)/white (1)
    DEV_Digital_Write(EPD_DC_PIN, 1);
    for (i = 0; i < Width * Height; i++)
    {
        // EPD_2IN9B_Z94_Grey_SendData(0xFF);
        EPD_2IN9B_Z94_Grey_SendData2(0xFF);
    }
    EPD_2IN9B_Z94_Grey_SendCommand(0x26); // write RAM for black(0)/white (1)
    DEV_Digital_Write(EPD_DC_PIN, 1);
    for (i = 0; i < Width * Height; i++)
    {
        // EPD_2IN9B_Z94_Grey_SendData(0x00);
        EPD_2IN9B_Z94_Grey_SendData2(0x00);
    }
    EPD_2IN9B_Z94_Grey_SendCommand(0x22); // Display Update Control
    EPD_2IN9B_Z94_Grey_SendData(0xF7);
    EPD_2IN9B_Z94_Grey_SendCommand(0x20);   // Activate Display Update Sequence
    EPD_2IN9B_Z94_Grey_ReadBusy(20 * 1000); // 9s
}

/******************************************************************************
function :	Sends the image buffer in RAM to e-Paper and displays
parameter:
******************************************************************************/
void EPD_2IN9B_Z94_Grey_Display(unsigned char *BW_Image, unsigned char *R_Image)
{
    UDOUBLE Width, Height;
    Width = (EPD_2IN9B_Z94_Grey_WIDTH % 8 == 0) ? (EPD_2IN9B_Z94_Grey_WIDTH / 8) : (EPD_2IN9B_Z94_Grey_WIDTH / 8 + 1);
    Height = EPD_2IN9B_Z94_Grey_HEIGHT;

    // send black data

    EPD_2IN9B_Z94_Grey_SendCommand(0x24);
    DEV_Digital_Write(EPD_DC_PIN, 1);
    EPD_2IN9B_Z94_Grey_SendData2(BW_Image, Width * Height);

    EPD_2IN9B_Z94_Grey_SendCommand(0x26);
    DEV_Digital_Write(EPD_DC_PIN, 1);
    EPD_2IN9B_Z94_Grey_SendData2(R_Image, Width * Height);

    EPD_2IN9B_Z94_Grey_SendCommand(0x22); // Display Update Control
    EPD_2IN9B_Z94_Grey_SendData(0xC7);
    // EPD_2IN9B_Z94_Grey_SendData(0xF7);
    EPD_2IN9B_Z94_Grey_SendCommand(0x20); // Activate Display Update Sequence
    EPD_2IN9B_Z94_Grey_ReadBusy(15 * 1000);
}

/******************************************************************************
function :	Enter sleep mode
parameter:
******************************************************************************/
void EPD_2IN9B_Z94_Grey_Sleep(void)
{
    EPD_2IN9B_Z94_Grey_SendCommand(0x10); // enter deep sleep
    EPD_2IN9B_Z94_Grey_SendData(0x01);
    DEV_Delay_ms(100);
}

/******************************************************************************
function :	Turn On Display
parameter:
******************************************************************************/
// void EPD_2IN9B_Z94_Grey_TurnOnDisplay(void)
// {
//     EPD_2IN9B_Z94_Grey_SendCommand(0x22); // Display Update Control
//     EPD_2IN9B_Z94_Grey_SendData(0xF7);
//     EPD_2IN9B_Z94_Grey_SendCommand(0x20); // Activate Display Update Sequence
//     EPD_2IN9B_Z94_Grey_ReadBusy(15 * 1000);
// }

void EPD_2IN9B_Z94_Grey_TurnOnDisplay(uint8_t part)
{
    EPD_2IN9B_Z94_Grey_SendCommand(0x22); // Display Update Control
    EPD_2IN9B_Z94_Grey_SendData(part ? 0xC7 : 0xF7);
    EPD_2IN9B_Z94_Grey_SendCommand(0x20); // Activate Display Update Sequence
    EPD_2IN9B_Z94_Grey_ReadBusy(15 * 1000);
}

/******************************************************************************
function :	Sends the image buffer in RAM to e-Paper and displays
parameter:  color:black,0;red,1;*data;index;length
******************************************************************************/
void EPD_2IN9B_Z94_Grey_Data_Write(UBYTE color, UBYTE *Image_Data, UDOUBLE index, UDOUBLE length)
{
    if (index == 0)
    // if (1)
    {
        if (color == 0)
        {
            EPD_2IN9B_Z94_Grey_SendCommand(0x24);
        }
        else if (color == 1)
        {
            EPD_2IN9B_Z94_Grey_SendCommand(0x26);
        }
        DEV_Digital_Write(EPD_DC_PIN, 1);
    }

    UDOUBLE Width, Height;
    Width = (EPD_2IN9B_Z94_Grey_WIDTH % 8 == 0) ? (EPD_2IN9B_Z94_Grey_WIDTH / 8) : (EPD_2IN9B_Z94_Grey_WIDTH / 8 + 1);
    Height = EPD_2IN9B_Z94_Grey_HEIGHT;

    // if(length==(Width*Height))
    // {
    //     for (UDOUBLE j = 0; j < Height; j++)
    //     {
    //         for (UDOUBLE i = 0; i < Width; i++)
    //         {
    //             EPD_2IN9B_Z94_Grey_SendData(Image_Data[i + (Height-j) * Width]);
    //         }
    //     }

    // }
    // else{
#ifdef EPD_SPI_ENABLE
    EPD_2IN9B_Z94_Grey_SendData2(Image_Data, length);
#else
    for (UDOUBLE i = 0; i < length; i++)
    {
        if (color == 0)
        {
            // DEV_Digital_Write(EPD_DC_PIN, 1);
            // DEV_Digital_Write(EPD_CS_PIN, 0);
            EPD_2IN9B_Z94_Grey_SendData2(Image_Data[i]);
            // DEV_Digital_Write(EPD_CS_PIN, 1);
        }
        else if (color == 1)
        {
            // DEV_Digital_Write(EPD_DC_PIN, 1);
            // DEV_Digital_Write(EPD_CS_PIN, 0);
            EPD_2IN9B_Z94_Grey_SendData2(Image_Data[i]);
            // DEV_Digital_Write(EPD_CS_PIN, 1);
        }
    }
#endif
    // }
}

void EPD_2IN9B_Z94_Grey_setDepth(uint8_t i)
{
    iLut = i ? (i > 15 ? 15 : i) : 15;
}

#if 1
int8_t EPD_2IN9B_Z94_Grey_ReadTemp()
{
    int8_t rc=0;

    // EPD_SSD_SendCommand(0x12); // soft reset
    // EPD_SSD_WaitBusy(100);
    // EPD_2IN9B_Z94_Grey_Reset();

    // EPD_2IN9B_Z94_Grey_ReadBusy(100);
    EPD_2IN9B_Z94_Grey_SendCommand(0x12); // SWRESET
    // EPD_2IN9B_Z94_Grey_ReadBusy(1000);
    DEV_Delay_us(200);

    // Border Waveform
    EPD_2IN9B_Z94_Grey_SendCommand(0x3C);
    EPD_2IN9B_Z94_Grey_SendData(0x05);

    // Temperature sensor control
    EPD_2IN9B_Z94_Grey_SendCommand(0x18);
    EPD_2IN9B_Z94_Grey_SendData(0x80); // 80: internal sensor 48: external sensor

    // Display update control
    EPD_2IN9B_Z94_Grey_SendCommand(0x22);
    EPD_2IN9B_Z94_Grey_SendData(0xb1); // full: 0xf7

    // Master Activation
    EPD_2IN9B_Z94_Grey_SendCommand(0x20);
    // EPD_SSD_WaitBusy(100);
    EPD_2IN9B_Z94_Grey_ReadBusy();

    // read temperature
    EPD_2IN9B_Z94_Grey_SendCommand(0x1b);
    rc = EPD_SSD_ReadData();

    return rc;
}
#endif



